package xfuzzy.xfghl.evaluation;

import java.util.Observer;
import java.util.Vector;

import xfuzzy.xfghl.codification.DoubleChromosome;
import xfuzzy.xfghl.model.XfghlConfig;
import xfuzzy.xfghl.population.Population;
import xfuzzy.xfhl.model.XfhlData;

/**
 * Clase que se encarga de la evaluacion de los individuos de la poblacion
 * @author Alberto David Fernandez Fernandez
 * */

public class EvaluationXfuzzy {
	
	/**
	 * Objeto que conecta las evaluaciones con la vista
	 * */
	private Observer observer;
	
	/**
	 * Lista de individuos evaluados
	 * */
	private Vector<DoubleChromosome> evaluated;
	
	/**
	 * Constructor de la clase
	 * */
	
	public EvaluationXfuzzy()  {
		
		this.evaluated = new Vector<DoubleChromosome>();
	}
	
	/**
	 * Metodo que evalua toda la poblacion de individuos
	 * @param population Poblacion a evaluar
	 * @param config Configuracion de la herramienta Xfghl
	 * */
	
	public void evaluarPoblacion(Population population, XfghlConfig config)  {
		
		XfghlThread [] xfghlthreads = null;
		Thread [] threads = null;
		int indexThread = 0;
		threads = new Thread[config.getNumThread()];
		xfghlthreads = new XfghlThread[config.getNumThread()];
		for (int i = 0; i < config.getNumThread(); i++)  {
			xfghlthreads[i] = new XfghlThread(config, new XfhlData(i, config.getnumIterAjust()));
			xfghlthreads[i].addObserver(this.observer);
		}
		
		for (DoubleChromosome chromosome : population.getIndividuos())  {
			 xfghlthreads[indexThread].addChromosome(chromosome);
			 indexThread = (indexThread + 1) % config.getNumThread();
		}
		for (int i = 0; i < config.getNumThread(); i++)  {
			 threads[i] = new Thread(xfghlthreads[i]);
			 threads[i].start();
		}
		for (int i = 0; i < config.getNumThread(); i++)  {
			try {
				threads[i].join();
			} 
			catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * Metodo que evalua dos individuos de la poblacion
	 * @param nuevo1 Individuo a evaluar
	 * @param nuevo2 Individuo a evaluar
	 * @param config Configuracion de la herramienta Xfghl
	 * */
	
	public void evaluarIndividuos(DoubleChromosome nuevo1, DoubleChromosome nuevo2, XfghlConfig config)  {
		
		int nthreads = 2;
		XfghlThread [] xfghlthreads = new XfghlThread[nthreads];
		Thread [] threads = new Thread[nthreads];
		XfhlData data1 = new XfhlData(0, config.getnumIterAjust());
		XfhlData data2 = new XfhlData(1, config.getnumIterAjust());
		xfghlthreads[0] = new XfghlThread(config, data1, nuevo1, evaluated);
		xfghlthreads[1] = new XfghlThread(config, data2, nuevo2, evaluated);
		xfghlthreads[0].addObserver(this.observer);
		xfghlthreads[1].addObserver(this.observer);
		threads[0] = new Thread(xfghlthreads[0]);
		threads[1] = new Thread(xfghlthreads[1]);
		for (int i = 0; i < nthreads; i++)  {
			 threads[i].start();
		}
		
		for (int i = 0; i < nthreads; i++)  {
			 try {
				threads[i].join();
			 } 
			 catch (InterruptedException e) {
				 e.printStackTrace();
			 }
		}
	}
	
	public void setObserver(Observer obs)  {
		
		this.observer = obs;
	}
}